//
// Created by vivi on 25/07/2017.
//

//#pragma once
//
#include <gtest/gtest.h>
#include <Eigen/Eigen>
#include "HairCoreMath.h"
#include <random>

TEST(GridPoint3D, TestRunWell) {

    for (size_t n = 0; n < 5; ++n) {
        //number of times

        //generate some random point
        size_t number_of_points = 100000;
        Eigen::VectorXf points(number_of_points * 3);
        //all points in 0-1
        for (size_t i = 0; i < number_of_points * 3; i++)
            points(i) = static_cast<float>(rand()) / static_cast<float>(RAND_MAX);

        XRwy::HairCoreMath::GridPoint3D grid(points, {0.04, 0.04, 0.04});

        size_t number_of_query = 100;
        for (size_t i = 0; i < number_of_query; ++i) {
            XRwy::Float3 query_points {
                    static_cast<float>(rand()) / static_cast<float>(RAND_MAX),
                    static_cast<float>(rand()) / static_cast<float>(RAND_MAX),
                    static_cast<float>(rand()) / static_cast<float>(RAND_MAX)
            };

            float query_raidus = 0.05f;

            const auto & query_results = grid.query_radius(query_points, query_raidus);

            //a naive check is used
            std::unordered_set<size_t> check_results;
            for (size_t j = 0; j < number_of_points * 3; j += 3) {
                float x = points(j) - query_points.x;
                float y = points(j + 1) - query_points.y;
                float z = points(j + 2) - query_points.z;
                if (x * x + y * y + z * z < query_raidus * query_raidus)
                    check_results.insert(j / 3);
            }

            ASSERT_EQ(query_results.size(), check_results.size());
            for (const auto &query_result_idx : query_results)
                ASSERT_TRUE(check_results.find(query_result_idx) != check_results.end());
        }
    }
}
